今天我們要進入資料庫設計的核心環節。我們的系統分為兩種資料:「全世界共用的寶可夢基礎資料 (圖鑑)」以及「每個玩家自己擁有的捕獲紀錄」。要怎麼在資料庫中優雅地儲存這些資料呢?
我們使用了兩張主要的資料表,並透過 pokemon_id 與 player_id 建立關聯:
-- 1. 寶可夢基礎圖鑑表 (全站共用)
CREATE TABLE pokemon_base (
pokemon_id INTEGER PRIMARY KEY, -- 全國圖鑑編號
name_zh TEXT NOT NULL,
name_en TEXT NOT NULL,
generation INTEGER,
-- (其他基礎屬性省略)
);
-- 2. 玩家持有紀錄表 (每個人抓到的各不相同)
CREATE TABLE user_pokemon_holdings (
holding_id INTEGER PRIMARY KEY AUTOINCREMENT,
player_id TEXT NOT NULL, -- 這是誰抓的?
pokemon_id INTEGER NOT NULL, -- 抓到哪隻? (Foreign Key)
gender TEXT, -- 公、母或無性別
is_shiny BOOLEAN DEFAULT 0, -- 是否為色違
is_lucky BOOLEAN DEFAULT 0, -- 是否為亮晶晶
notes TEXT, -- 玩家自訂備註
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (pokemon_id) REFERENCES pokemon_base(pokemon_id)
);
新手在設計資料庫時,很容易把所有東西塞在同一張表裡(這稱為反正規化 Denormalization),例如在持有紀錄表裡面,除了存玩家 ID,還直接存下寶可夢的名字、屬性、世代。
為什麼我們堅持要把「圖鑑」和「持有紀錄」拆成兩張表,並用 Foreign Key (正規化 Normalization) 關聯呢?
pokemon_id = 25,節省大量儲存空間。pokemon_base 改一次,所有玩家的皮卡丘屬性就會瞬間全部更新!FOREIGN KEY (pokemon_id) REFERENCES pokemon_base(pokemon_id),這確保了玩家絕對不可能抓到一隻「圖鑑上不存在 (id=9999)」的幽靈寶可夢,資料庫會在寫入時直接擋下這種錯誤資料。
使用資料庫視覺化工具 (例如 Turso Studio) 顯示
user_pokemon_holdings表格 Schema (欄位定義) 的畫面。
資料表結構規劃完畢,正規化的設計讓我們未來的維護更加輕鬆!有了資料表,明天我們要開始來處理系統的安全大門:「封閉式使用者帳號系統」。